package com.mysvg.hellosvg.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseEvent;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.shared.EventHandler;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

import org.vectomatic.dom.svg.OMSVGCircleElement;
import org.vectomatic.dom.svg.OMSVGDocument;
import org.vectomatic.dom.svg.OMSVGLength;
import org.vectomatic.dom.svg.OMSVGMatrix;
import org.vectomatic.dom.svg.OMSVGPoint;
import org.vectomatic.dom.svg.OMSVGRectElement;
import org.vectomatic.dom.svg.OMSVGSVGElement;
import org.vectomatic.dom.svg.utils.DOMHelper;
import org.vectomatic.dom.svg.utils.OMSVGParser;
import org.vectomatic.dom.svg.utils.SVGConstants;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
import java.util.Map;


/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Hellosvg implements EntryPoint {
	
	private OMSVGSVGElement svg;
	private boolean dragging;
	private boolean drawCircle = true;
	private boolean ifMove = false;
	
	private HorizontalPanel ctrlPanel = new HorizontalPanel();
	private VerticalPanel mainPanel = new VerticalPanel();
	//private HorizontalPanel xmlPanel = new HorizontalPanel();
	private Button circleButton = new Button("Circle");
	private Button svgButton = new Button("SVG");
	//private Button moveButton = new Button("Move");
	private Button clearButton = new Button("Clear");
	//private float x0,y0;
	private OMSVGPoint p;
	private OMSVGPoint pMove;
	private OMSVGDocument doc;
	private OMSVGRectElement outline;
	private OMSVGCircleElement circle; 
	private Vector<OMSVGCircleElement> circleList = new Vector<OMSVGCircleElement>();
	private Label xmlLabel = new Label();
	
	
	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		ctrlPanel.add(circleButton);
		//ctrlPanel.add(moveButton);
		ctrlPanel.add(clearButton);
		ctrlPanel.add(svgButton);
		//xmlPanel.add(xmlLabel);
		mainPanel.add(ctrlPanel);
		
		//xmlLabel.setText("XML:");
		
		circleButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				drawCircle = true;
				//ifMove = false;
			}	
		});
		
		/*
		moveButton.addClickHandler (new ClickHandler(){
			public void onClick(ClickEvent event){
				drawCircle = false;
				//ifMove = true;
			}
		});
		*/
		
		svgButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				Window.alert(svg.getMarkup());
			}
			
		});
		
		clearButton.addClickHandler (new ClickHandler(){
			public void onClick(ClickEvent event){
				for(int i=0;i<circleList.size();i++){
					svg.removeChild(circleList.get(i));
				}
				circleList.clear();
				event.stopPropagation();
				event.preventDefault();
			}
		});
		
		final OMSVGDocument doc = OMSVGParser.currentDocument();
		svg = doc.createSVGSVGElement();
		svg.setWidth(OMSVGLength.SVG_LENGTHTYPE_PX, 600);
		svg.setHeight(OMSVGLength.SVG_LENGTHTYPE_PX, 600);
		outline = doc.createSVGRectElement(0, 0, 600, 600, 0f, 0f);
		outline.getStyle().setSVGProperty(SVGConstants.CSS_STROKE_PROPERTY, SVGConstants.CSS_BLACK_VALUE);
		outline.getStyle().setSVGProperty(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_WHITE_VALUE);
		circle = doc.createSVGCircleElement();
		circle.getStyle().setSVGProperty(SVGConstants.CSS_STROKE_PROPERTY, SVGConstants.CSS_BLACK_VALUE);
		circle.getStyle().setSVGProperty(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_BLACK_VALUE);
		
		svg.addMouseDownHandler(new MouseDownHandler(){public void onMouseDown(MouseDownEvent event){
			dragging = true;
			p = getLocalCoordinates(event);
			if(drawCircle){
				circle = doc.createSVGCircleElement();
				circleList.add(circle);
			//circleList.get(i) = doc.createSVGCircleElement(80,80,40);
				circleList.get(circleList.size()-1).getStyle().setSVGProperty(SVGConstants.CSS_STROKE_PROPERTY, SVGConstants.CSS_BLACK_VALUE);
				circleList.get(circleList.size()-1).getStyle().setSVGProperty(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_BLACK_VALUE);
			
			//circle = doc.createSVGCircleElement(p.getX(),p.getY(),0);
				circleList.get(circleList.size()-1).getCx().getBaseVal().setValue(p.getX());
				circleList.get(circleList.size()-1).getCy().getBaseVal().setValue(p.getY());
				circleList.get(circleList.size()-1).getR().getBaseVal().setValue(0);
				/*
				circleList.get(circleList.size()-1).addMouseDownHandler(new MouseDownHandler(){
					public void onMouseDown(MouseDownEvent event){
						dragging = true;
						p = getLocalCoordinates(event);
					}
				});
				
				circleList.get(circleList.size()-1).addMouseUpHandler(new MouseUpHandler(){
					public void onMouseUp(MouseUpEvent event){
						dragging = false;
					}
				});
				
				circleList.get(circleList.size()-1).addMouseMoveHandler(new MouseMoveHandler(){
					public void onMouseMove(MouseMoveEvent event){
						if(dragging && ifMove){
							OMSVGPoint d = getLocalCoordinates(event);
							
						}
					}
				});
				*/
				svg.appendChild(circleList.get(circleList.size()-1));
			}
			event.stopPropagation();
			event.preventDefault();

			
		}});
		svg.addMouseUpHandler(new MouseUpHandler(){public void onMouseUp(MouseUpEvent event){
			dragging = false;
			//xmlLabel.setText(svg.getMarkup());
			event.stopPropagation();
			event.preventDefault();
		}});
		svg.addMouseMoveHandler(new MouseMoveHandler(){	public void onMouseMove(MouseMoveEvent event){
			if(dragging && drawCircle){
				OMSVGPoint d = getLocalCoordinates(event).substract(p);
				circleList.get(circleList.size()-1).getR().getBaseVal().setValue((float)Math.sqrt(d.getX()*d.getX()+d.getY()*d.getY()));
			}
			event.stopPropagation();
			event.preventDefault();
		}});
		/*
		if(circleList.size() == 0)
			svg.appendChild(circle);
		else
			svg.appendChild(circleList.get(circleList.size()-1));
			*/
		svg.appendChild(outline);
		
		/*
		mainPanel.getElement().appendChild(svg.getElement());
		mainPanel.add(xmlLabel);
		*/
		
		
		RootPanel.get().add(ctrlPanel);
		RootPanel.get().getElement().appendChild(svg.getElement());
		//RootPanel.get().add(xmlLabel);
		
		//RootPanel.get().add(mainPanel);
		
		//RootPanel.get().add(xmlLabel);
		//OMSVGCircleElement circle = doc.createSVGCircleElement(150, 150, 100);
		//circle.getStyle().setSVGProperty(SVGConstants.CSS_FILL_PROPERTY, "blue");
		//svg.appendChild(circle);
		//RootPanel.get().getElement().appendChild(svg.getElement());
	}
	
	//@Override
	
	

	
	

	private OMSVGPoint getLocalCoordinates(MouseEvent<? extends EventHandler> e) {
		OMSVGPoint p = svg.createSVGPoint(e.getClientX(),e.getClientY());
		OMSVGMatrix m = svg.getScreenCTM().inverse();
		return p.matrixTransform(m);
	}
}